<template>
  <view class="pro-tooltip" :style="{
			'--theme-bg-color': color
		}">
    <!-- #ifdef APP-PLUS -->
    <view class="pro-tooltip-content" @longpress="handleClick" @touchend="handleTouchEnd">
      <slot></slot>
      <view class="pro-tooltip-popper" @click.stop="() => {}" :style="[
				style,
				{
					visibility: isShow ? 'visible' : 'hidden',
					color: color === 'white' ? '' : '#fff',
					maxWidth: maxWidth + 'rpx',
					boxShadow: color === 'white' ? '0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d' : ''
				}
			]">
        <slot name="content">
          <rich-text v-if="richText" :nodes="content"></rich-text>
          <text v-else>{{ content }}</text>
        </slot>
        <view class="pro-popper-icon" :style="[arrowStyle]" :class="[
					{
					  'pro-popper-up': placement.indexOf('bottom') === 0,
						'pro-popper-arrow': placement.indexOf('top') === 0,
						'pro-popper-right': placement.indexOf('right') === 0,
						'pro-popper-left': placement.indexOf('left') === 0
					}
				]"></view>
      </view>
    </view>
    <!-- #endif -->
    <!-- #ifdef H5 -->
    <view class="pro-tooltip-content" @click="handleTipClick">
      <slot></slot>
      <view class="pro-tooltip-popper" @click.stop="() => {}" :style="[
					style,
					{
						visibility: isShow ? 'visible' : 'hidden',
						color: color === 'white' ? '' : '#fff',
						maxWidth: maxWidth + 'rpx',
						boxShadow: color === 'white' ? '0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d' : ''
					}
				]">
        <slot name="content">
          <rich-text v-if="richText" :nodes="content"></rich-text>
          <text v-else>{{ content }}</text>
        </slot>
        <view class="pro-popper-icon" :style="[arrowStyle]" :class="[
						{
						  'pro-popper-up': placement.indexOf('bottom') === 0,
							'pro-popper-arrow': placement.indexOf('top') === 0,
							'pro-popper-right': placement.indexOf('right') === 0,
							'pro-popper-left': placement.indexOf('left') === 0
						}
					]"></view>
      </view>
    </view>
    <!-- #endif -->
  </view>
</template>
<script>
  /**
	 * ProTooltip 文字提示气泡框
	 * @author denglei
	 * @description 文字提示--当文字过多没法全部显示的时候，使用tooltip组件，以气泡的方式进行展示，长按文本的时候展示气泡，按住不动，气泡不会消失，之后松开了，气泡才会在2s后自动消失
	 * @tutorial 
	 * @property {Boolean} visible =[true | false] 控制tooltip展示，隐藏
	 * @property {String} color = [#fff] 字体颜色
	 * @property {String} placement = [top|top-start|top-end|bottom|bottom-start|bottom-end|right|right-start|right-end|left|left-start|left-end] tooltip的出现位置
	 * @property {String} content = [] 文本内容
	 * @property {Boolean} show = [true | false] 是否展示tooltip
	 * @property {Boolean} richText = [true | false] 内容是否是富文本		
	 * @property {Number} maxWidth	tooltip气泡的最大宽度
	 * @example 	<pro-tooltip content="测试文本">测试文本</pro-tooltip>
	 *注意：因为uniapp 中小程序中没有window对象，需手动调用 关闭
        第一种办法关闭：this.$refs.tooltip.close()
          第二种办法关闭：visible.sync = false
	 */
  export default {
    name: 'ProTooltip',
    props: {
      visible: Boolean,
      color: {
        type: String,
        default: '#FFF'
      },
      placement: {
        type: String,
        default: 'top'
      },
      // 文本内容
      content: {
        type: String,
        default: ''
      },
      // 是否展示
      show: {
        type: Boolean,
        default: false
      },
      // 是否是富文本
      richText: {
        type: Boolean,
        default: false
      },
      // tooltip气泡的最大宽度
      maxWidth: {
        type: Number,
        default: 800
      }
    },

    data() {
      return {
        isShow: this.visible,
        title: 'Hello',
        arrowLeft: 0,
        query: null,
        style: {},
        arrowStyle: {}
      };
    },
    onLoad() {},
    watch: {
      isShow: {
        handler(val) {
          this.$emit('update:visible', val);
        },
        immediate: true
      },
      visible: {
        handler(val) {
          if (val) {
            this.$nextTick(() => {
              this.getPosition();
            });
          }
          this.isShow = val;
        },
        immediate: true
      }
    },
    mounted() {
      this.getPosition();
    },
    methods: {
      close() {
        this.isShow = false;
      },
      handleTouchEnd() {
        setTimeout(() => {
          this.isShow = false;
        }, 1500); //显示1.5秒后自动隐藏
      },
      async handleClick() {
        if (this.isShow) {
          return (this.isShow = false);
        }
        await this.getPosition();
        this.isShow = true;
      },
      async handleTipClick() {
        if (this.isShow) {
          return (this.isShow = false);
        }
        await this.getPosition();
        this.isShow = true;
        setTimeout(() => {
          this.isShow = false;
        }, 1500); //显示1.5秒后自动隐藏
      },
      getPosition() {
        return new Promise(resolve => {
          uni
            .createSelectorQuery()
            .in(this)
            .selectAll('.pro-tooltip-content,.pro-tooltip-popper')
            .boundingClientRect(async data => {
              let {
                left,
                bottom,
                right,
                top,
                width,
                height
              } = data[0];
              let obj1 = data[1];
              let objStyle = {};
              let objStyle1 = {};
              switch (this.placement) {
                case 'top':
                  if (obj1.width > width) {
                    objStyle.left = `-${(obj1.width - width) / 2}px`;
                  } else {
                    objStyle.left = `${Math.abs(obj1.width - width) / 2}px`;
                  }

                  objStyle.bottom = `${height + 8}px`;
                  objStyle1.left = obj1.width / 2 - 6 + 'px';
                  break;
                case 'top-start':
                  objStyle.left = `0px`;
                  objStyle.bottom = `${height + 8}px`;
                  break;
                case 'top-end':
                  objStyle.right = `0px`;
                  objStyle.bottom = `${height + 8}px`;
                  objStyle1.right = `8px`;
                  break;
                case 'bottom':
                  if (obj1.width > width) {
                    objStyle.left = `-${(obj1.width - width) / 2}px`;
                  } else {
                    objStyle.left = `${Math.abs(obj1.width - width) / 2}px`;
                  }
                  objStyle.top = `${height + 8}px`;
                  objStyle1.left = obj1.width / 2 - 6 + 'px';
                  break;
                case 'bottom-start':
                  objStyle.left = `0px`;
                  objStyle.top = `${height + 8}px`;
                  objStyle1.left = `8px`;
                  break;

                case 'bottom-end':
                  objStyle.right = `0px`;
                  objStyle.top = `${height + 8}px`;
                  objStyle1.right = `8px`;
                  break;

                case 'right':
                  objStyle.left = `${width + 8}px`;
                  if (obj1.height > height) {
                    objStyle.top = `-${(obj1.height - height) / 2}px`;
                  } else {
                    objStyle.top = `${Math.abs((obj1.height - height) / 2)}px`;
                  }

                  objStyle1.top = `${obj1.height / 2 - 6}px`;
                  break;
                case 'right-start':
                  objStyle.left = `${width + 8}px`;
                  objStyle.top = `0px`;
                  objStyle1.top = `8px`;
                  break;

                case 'right-end':
                  objStyle.left = `${width + 8}px`;
                  objStyle.bottom = `0px`;
                  objStyle1.bottom = `8px`;
                  break;

                case 'left':
                  objStyle.right = `${width + 8}px`;

                  if (obj1.height > height) {
                    objStyle.top = `-${(obj1.height - height) / 2}px`;
                  } else {
                    objStyle.top = `${Math.abs((obj1.height - height) / 2)}px`;
                  }

                  objStyle1.top = `${obj1.height / 2 - 6}px`;
                  break;

                case 'left-start':
                  objStyle.right = `${width + 8}px`;
                  objStyle.top = `0px`;
                  objStyle1.top = `8px`;
                  break;

                case 'left-end':
                  objStyle.right = `${width + 8}px`;
                  objStyle.bottom = `0px`;
                  objStyle1.bottom = `8px`;
                  break;
              }
              this.style = objStyle;
              // 三角形箭头
              this.arrowStyle = objStyle1;
              resolve();
            })
            .exec();
        });
      }
    }
  };
</script>

<style lang="scss" scoped>
  $theme-bg-color: #333;

  .pro-tooltip {
    position: relative;
  }

  .pro-tooltip-content {
    position: relative;
    height: 100%;
    display: inline-block;
  }

  .pro-tooltip-popper {
    visibility: hidden;
    position: absolute;
    display: block;
    margin-top: 6rpx;
    border-radius: 8rpx;
    padding: 20rpx;
    min-width: 200rpx;
    max-width: 600rpx;
    word-wrap: break-word;
    white-space: wrap;
    z-index: 9999;
    font-size: 32rpx;
    line-height: 44rpx;
    background: $theme-bg-color;
  }

  .pro-popper-icon {
    width: 0;
    height: 0;
    z-index: 9;
    position: absolute;
  }

  .pro-popper-arrow {
    bottom: -5px;
    /* transform-origin: center top; */
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-top: 6px solid $theme-bg-color;
  }

  .pro-popper-right {
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-right: 6px solid $theme-bg-color;
    left: -5px;
  }

  .pro-popper-left {
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-left: 6px solid $theme-bg-color;
    right: -5px;
  }

  .pro-popper-up {
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-bottom: 6px solid $theme-bg-color;
    top: -5px;
  }
</style>